/*
 * @Descripttion:配置合并
 * @version:
 * @Author: 周志国
 * @Date: 2021-06-16 10:10:38
 * @LastEditors: 周志国
 * @LastEditTime: 2022-08-01 16:00:10
 * @changeLog:
 * @FilePath: /anov-next/src/assets/js/app/indexhandler/configHandler.js
 */
import router from '@/router'
import App from '@/App'
import { cloneDeep } from 'dtc'
import { mergeWith } from 'lodash'
import cmlGlobal from '@/assets/js/app/cmlpanel/util/cmlGlobal'
import { getStoredData } from '@/assets/js/app/utils/sys-utils/tools.js'
import defaultConfig from '@/assets/js/app/config'
import { modal } from '@/assets/js/app/message'
import validateHandler from './validateHandler'
import { adminServer, chipServer, runtimeServer } from 'anov-core'
import appStore from '@/store'

const ENV = process.env.NODE_ENV
const event = {
  //服务器芯片配置加载
  serverChip: 'ChipConfig_server',
  //本地芯片配置加载
  localChip: 'ChipConfig_local',
  //运行时配置加载
  runtimeConfig: 'RuntimeConfig',
  // 配置合并完成
  configMergeEnd: 'configMergeEnd'
}
//配置优先级: defaultConfig <- storedConfig <- publicConfig <- objectARXConfig <- chipConfig <- runtimeConfig

const configMerge = {
  ...runtimeServer.getEventBus(),
  event,
  defaultConfig,
  serverChipCode: 20000, //后续待统一处理  errorCode
  objectARXConfig: null,
  beforeChipConfig: null,
  beforeRuntimeConfig: null,
  afterRuntimeConfig: null,
  __initValidError: validateHandler.initValidError,
  init(objectARXConfig) {
    // 第三方注入配置
    this.objectARXConfig = objectARXConfig
    this.$on(this.event.serverChip, this.__serverChip.bind(this))
    this.$on(this.event.localChip, this.__localChip.bind(this))
    this.$on(this.event.runtimeConfig, this.__runtimeConfig.bind(this))
    this.beforeChipConfigMerge()
    this.getChipConfig(this.beforeChipConfig)
  },
  // save default config copy
  getDefaultConfig() {
    if (!window.__ANOV__DEFAUIT__CONFIG) {
      defaultConfig.page = { pages: this.__getDefaultPage(), destroyParts: [] }
      let userPageSize = { w: App.pageSize.width, h: App.pageSize.height }
      Object.assign(defaultConfig.env.designSize, userPageSize)
      let defCfig = cloneDeep(defaultConfig)
      delete defCfig.license
      delete defCfig.panel.permission
      window.__ANOV__DEFAUIT__CONFIG = defCfig
    }
    return defaultConfig
  },
  // 获取持久化配置
  getStoredConfig() {
    const lsn = `${cmlGlobal.projectLocalDir}_${
      cmlGlobal.projectId
    }_${cmlGlobal.platformVersion.replace(/\./g, '-')}_${cmlGlobal.projectTime}`
    let storedConfig = getStoredData(lsn)
    if (ENV === 'development') {
      // 开发环境特殊处理数据源,不对数据源做持久化处理
      let optDataSource = {},
        storedDataSource = storedConfig.dataSource,
        defaultDataSource = this.getDefaultConfig().dataSource || {}
      storedDataSource &&
        (storedDataSource.type = optDataSource.type || defaultDataSource.type)
    }
    return storedConfig
  },
  beforeChipConfigMerge() {
    this.__handlePage(window.__ANOV__PUBLIC__CONFIG)
    this.__handlePage(this.objectARXConfig)
    this.beforeChipConfig = mergeWith(
      this.getDefaultConfig(),
      this.getStoredConfig(),
      window.__ANOV__PUBLIC__CONFIG,
      this.objectARXConfig,
      (objVal, srcVal, key, object, source, stack) => {
        if (key === 'themes' && !srcVal.length) {
          return undefined
        }
        if (key === 'page') {
          if (srcVal.pages?.length > 0 || srcVal?.destroyParts > 0) {
            return srcVal
          } else {
            return objVal
          }
        }
        if (key == '!page' && Array.isArray(objVal)) {
          return srcVal
        }
      }
    )
  },
  getChipConfig(config) {
    if (config.admin.serverPath) {
      this.$emit(this.event.serverChip)
    } else {
      this.$emit(this.event.localChip)
    }
  },
  __serverChip() {
    let key = cmlGlobal.projectId
    let code = appStore.state.env.customer.info.code
    adminServer.init(this.beforeChipConfig)
    adminServer
      .getConfig({ key, code }, (res) => {
        if (!res) {
          this.$emit(this.event.localChip)
          return
        }
        if (res.code !== this.serverChipCode) {
          this.__initValidError({
            code: res.code,
            msg: res.msg,
            chip: 'remote'
          })
          return
        }
        if (!res.data.verify) {
          this.__initValidError({
            code: res.code,
            msg: res.msg,
            chip: 'remote'
          })
          return
        }
        appStore.commit('env/setCustomerInfo', {
          code: res.data.clientCode,
          address: res.data.clientIpInfo,
          ip: res.data.clientIp,
          projectId: key
        })
        appStore.commit('env/setCity', res.data.clientIpInfo)
        this.$emit(this.event.localChip, res.data.screenCore)
      })
      .catch((err) => {
        console.warn(`get config error. ${err}`)
      })
  },
  //合并芯片
  __localChip(chip) {
    chipServer.addEventListener('configLoad', (chipConfig) => {
      this.beforeRuntimeConfig = mergeWith(
        this.beforeChipConfig,
        chipConfig.result
      )
      if (chipConfig.isDropLoad) {
        let msg = this.__compareConfig(
          this.beforeRuntimeConfig,
          chipConfig.result
        )
        modal.open({
          componentsName: 'chipLoad',
          content: msg,
          type: 'success',
          style: {
            width: '600px',
            height: '600px'
          }
        })
        return
      }
      this.$emit(this.event.runtimeConfig)
    })
    chipServer.addEventListener('error', (e) => {
      log(e, 'error')
    })
    chipServer.addEventListener('notValid', (e) => {
      log(e, 'notValid')
    })
    chip
      ? appStore.commit('env/setChip', 'remote')
      : appStore.commit('env/setChip', 'local')
    const cfg = chip ? { configPath: chip } : {}
    chipServer.init(cfg)
  },
  // 运行时服务
  __runtimeConfig() {
    let root = app.root ? Object.assign(app.root, app) : null
    runtimeServer.init(this.beforeRuntimeConfig)
    runtimeServer.setCurrentContext(root)
    this.__handlePage(this.beforeRuntimeConfig)
    this.afterRuntimeConfig = this.beforeRuntimeConfig
    this.$emit(this.event.configMergeEnd, this.afterRuntimeConfig)
  },
  // 获取页面初始化配置
  __getDefaultPage() {
    let pagesArr = []
    router.options.routes.forEach((route) => {
      if (route.path == '/' || route.path == '*') return
      let pageConfig = {
        name: route.name,
        nameText: route.nameText,
        path: route.path,
        tlConfig: route.component.timeline,
        parts: route.component.pageConfig,
        reverseTimeScale: route.component.reverseTimeScale || 3
      }
      pagesArr.push(cloneDeep(pageConfig))
    })
    return pagesArr
  },
  // 拖拽芯片 显示信息
  __compareConfig(oldConfig, newConfig) {
    let _ = app.root
    let str = ''
    newConfig.panel.permission.map((newItem) => {
      let isFind = oldConfig.panel.permission.find((oldItem) => {
        return newItem == oldItem
      })
      str +=
        _.$t(chipServer.configI18nMapping[newItem]) +
        ':' +
        (!isFind ? _.$t('chip.newAuthorization') : _.$t('chip.authorized')) +
        '<br>'
    })
    return str
  },
  // 处理页面信息
  __handlePage(config) {
    if (Array.isArray(config.pages) && config.pages.length > 0) {
      for (let i = 0; i < config.pages.length; i++) {
        !config.pages[i].name && (config.pages[i].name = 'anov_undefind')
        !config.pages[i].path && (config.pages[i].path = '/anov_undefind')
        !config.pages[i].parts && (config.pages[i].parts = [])
        !config.pages[i].tlConfig && (config.pages[i].tlConfig = {})
        !config.pages[i].reverseTimeScale &&
          (config.pages[i].reverseTimeScale = 3)
      }
      config.page = { pages: config.pages }
    }
    if (Array.isArray(config.destroyParts) && config.destroyParts.length > 0) {
      config.page.destroyParts = config.destroyParts
    }
  }
}
export default configMerge
